/**
 * [162] 寻找峰值
 * 思路：
 * # O(log n) 盲猜二分法
 * tips：
 * # nums[i] != nums[i+1]，相邻元素不相等，非增即减
 * # 可以此作为左右指针的收敛条件：增 l->m 减 m<-r
 * @format
 * @lc app=leetcode.cn id=162 lang=javascript
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @return {number}
 */
// 二分法：逻辑优化
// 以 left = right 作为循环终止条件，减少循环内逻辑判断
var findPeakElement = function (nums) {
    let [l, r, m] = [0, nums.length - 1, 0]
    while (l < r) {
        m = Math.floor((l + r) / 2)
        // 由于是向下取整，所以当 [l,r] 区间长度缩减 2 时 m+1 不会越界
        if (nums[m] > nums[m + 1]) r = m
        // +1 防止向下取整导致无限循环
        else l = m + 1
    }
    return l
}
// 二分法
// var findPeakElement = function (nums) {
//     const N = nums.length
//     // 数组长度为 1
//     if (N == 1) return 0
//     // 峰值在两边
//     nums[-1] = -Infinity
//     nums[N] = -Infinity
//     if (nums[0] > nums[1]) return 0
//     if (nums[N - 1] > nums[N - 2]) return N - 1
//     // 峰值在中间
//     let [left, right, mid] = [0, N - 1, Math.floor(N / 2)]
//     while (true) {
//         const CASE = 2 * (nums[mid] > nums[mid - 1]) + (nums[mid] > nums[mid + 1])
//         switch (CASE) {
//             // 低谷
//             case 0:
//                 right = mid
//                 break
//             // 递减
//             case 1:
//                 right = mid
//                 break
//             // 递增
//             case 2:
//                 left = mid
//                 break
//             // 顶峰
//             case 3:
//                 return mid
//         }
//         mid = Math.floor((left + right) / 2)
//     }
// }
// debugger
// const nums = [2, 1]
// const TOP = findPeakElement(nums)
// console.log(TOP)
// @lc code=end
